package com.lib.common.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Message;

import androidx.annotation.ArrayRes;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatTextView;

import android.util.AttributeSet;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import com.lib.common.R;

import java.lang.ref.WeakReference;

public class AnimTextView extends AppCompatTextView {

    private static final int DEFAULT_IN_ANIM = R.anim.fade_in;
    private static final int DEFAULT_OUT_ANIM = R.anim.fade_out;

    private Animation mFadeInAnimation;
    private Animation mFadeOutAnimation;

    private CharSequence[] mSequences;
    private boolean mIsShown;
    private int mPosition;
    private int mIntervalMillis = 1500;

    private InnerHandler mHandler = new InnerHandler(this);

    private static class InnerHandler extends Handler {

        private final WeakReference<AnimTextView> mWr;

        private InnerHandler(AnimTextView v) {
            mWr = new WeakReference<>(v);
        }

        @Override
        public void handleMessage(Message msg) {
            AnimTextView view = mWr.get();
            if (view == null) {
                return;
            }
            view.startAnimation(view.mFadeOutAnimation);
            view.getAnimation().setAnimationListener(new Animation.AnimationListener() {

                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    AnimTextView view = mWr.get();
                    if (view == null) {
                        return;
                    }
                    if (view.mIsShown) {
                        view.mPosition = view.mPosition == view.mSequences.length - 1 ? 0 : view.mPosition + 1;
                        view.startAnimation();
                    }
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
        }
    }

    public AnimTextView(Context context) {

        this(context, null);
    }

    public AnimTextView(Context context, AttributeSet attrs) {

        this(context, attrs, 0);
    }

    public AnimTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.AnimTextView);
        mSequences = ta.getTextArray(R.styleable.AnimTextView_arrays);
        mIntervalMillis = ta.getInteger(R.styleable.AnimTextView_intervalMillis, mIntervalMillis);
        int resIdFadeIn = ta.getResourceId(R.styleable.AnimTextView_inAnim, DEFAULT_IN_ANIM);
        int resIdFadeOut = ta.getResourceId(R.styleable.AnimTextView_outAnim, DEFAULT_OUT_ANIM);
        ta.recycle();

        mIsShown = true;
        mFadeInAnimation = AnimationUtils.loadAnimation(context, resIdFadeIn);
        mFadeOutAnimation = AnimationUtils.loadAnimation(context, resIdFadeOut);
        mFadeInAnimation.setDuration(mIntervalMillis);
        mFadeOutAnimation.setDuration(mIntervalMillis);
    }

    public void resume() {
        mIsShown = true;
        startAnimation();
    }

    public void pause() {
        mIsShown = false;
        stopAnimation();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        pause();
    }

    @Override
    protected void onAttachedToWindow() {

        super.onAttachedToWindow();
        resume();
    }

    public CharSequence[] getTexts() {
        return mSequences;
    }

    public void setTexts(@ArrayRes int texts) {
        if (getResources().getStringArray(texts).length < 1) {
            throw new IllegalArgumentException("There must be at least one text");
        }
        stopAnimation();
        mPosition = 0;
        startAnimation();
    }

    public void setTexts(@NonNull String[] texts) {

        if (texts.length < 1) {
            throw new IllegalArgumentException("There must be at least one text");
        }
        this.mSequences = texts;
        stopAnimation();
        mPosition = 0;
        startAnimation();
    }

    public void setInAnimation(Context context, int fadeIn) {

        mFadeInAnimation = AnimationUtils.loadAnimation(context, fadeIn);
    }

    public void setOutAnimation(Context context, int fadeOut) {

        mFadeOutAnimation = AnimationUtils.loadAnimation(context, fadeOut);
    }

    public void setIntervalMillis(int intervalMillis) {

        this.mIntervalMillis = intervalMillis;
        mFadeInAnimation.setDuration(mIntervalMillis);
        mFadeOutAnimation.setDuration(mIntervalMillis);
    }

    private void stopAnimation() {

        mHandler.removeCallbacksAndMessages(null);
        if (getAnimation() != null) {
            getAnimation().cancel();
        }
    }

    protected void startAnimation() {

        setText(mSequences[mPosition]);
        startAnimation(mFadeInAnimation);
        mHandler.sendEmptyMessageDelayed(0, mIntervalMillis);
    }
}